# Which CPU to start domain on?
#cpu = -1 # leave to Xen to pick
+# Disable vif for now
+nics=0
+
# Optionally define mac and/or bridge for the network interfaces.
# Random MACs are assigned if not given.
#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ]
#define __ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
+register unsigned long ia64_r13 asm ("r13") __attribute_used__;
#define __ia64_getreg(regnum) \
({ \
uint64_t ia64_intri_res; \
#########################################################
DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-LIBS+=-lm -L../../libxc -lxenctrl
+LIBS+=-lm -L../../libxc -lxenctrl -lxenguest
ifndef CONFIG_USER_ONLY
LIBS+=-lz
endif
#elif defined(__ia64__)
#include "ia64_intrinsic.h"
-#define cpu_get_reak_ticks() \
- ia64_getreg(_IA64_REG_AR_ITC)
+#define cpu_get_real_ticks() \
+ __ia64_getreg(_IA64_REG_AR_ITC)
#else
#error unsupported CPU
int memsize,
const char *image_name,
unsigned int control_evtchn,
+ unsigned int lapic,
unsigned int vcpus,
unsigned int store_evtchn,
unsigned long *store_mfn)
/* currently done by hypervisor, should move here */
/* ctxt->regs.r28 = dom_fw_setup(); */
ctxt->vcpu.privregs = 0;
- ctxt->sys_pgnr = nr_pages - 3;
+ ctxt->sys_pgnr = 3;
i = 0; /* silence unused variable warning */
#else /* x86 */
/*
OBJS += vmx_init.o vmx_virt.o vmx_vcpu.o vmx_process.o vmx_vsa.o vmx_ivt.o\
vmx_phy_mode.o vmx_utility.o vmx_interrupt.o vmx_entry.o vmmu.o \
vtlb.o mmio.o vlsapic.o vmx_hypercall.o mm.o vmx_support.o \
- pal_emul.o vmx_irq_ia64.o
+ pal_emul.o vmx_irq_ia64.o vmx_vioapic.o
# lib files from xen/arch/ia64/linux/ (linux/arch/ia64/lib)
OBJS += bitop.o clear_page.o flush.o copy_page_mck.o \
|| ln -s $(BASEDIR)/include/xen $(BASEDIR)/include/linux
[ -e $(BASEDIR)/include/asm-ia64/xen ] \
|| ln -s $(BASEDIR)/include/asm-ia64/linux $(BASEDIR)/include/asm-ia64/xen
+# Link to DM file in Xen for ia64/vti
+ [ -e $(BASEDIR)/include/asm-ia64/vmx_vioapic.h ] \
+ || ln -s ../../include/asm-x86/vmx_vioapic.h $(BASEDIR)/include/asm-ia64/vmx_vioapic.h
+ [ -e $(BASEDIR)/arch/ia64/vmx/vmx_vioapic.c ] \
+ || ln -s ../../../arch/x86/dm/vmx_vioapic.c $(BASEDIR)/arch/ia64/vmx/vmx_vioapic.c
# Solve circular reference on asm-offsets.h
[ -f $(BASEDIR)/include/asm-ia64/asm-offsets.h ] \
|| echo "#define IA64_TASK_SIZE 0" > $(BASEDIR)/include/asm-ia64/asm-offsets.h
-I$(BASEDIR)/include/asm-ia64/linux-null \
-I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
CFLAGS += -Wno-pointer-arith -Wredundant-decls
-CFLAGS += -DIA64 -DXEN -DLINUX_2_6
+CFLAGS += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY
CFLAGS += -ffixed-r13 -mfixed-range=f12-f15,f32-f127
CFLAGS += -w -g
ifeq ($(VALIDATE_VT),y)
return;
}
+extern struct vmx_mmio_handler vioapic_mmio_handler;
static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir)
{
struct virutal_platform_def *v_plat;
//mmio_type_t iot;
unsigned long iot;
+ struct vmx_mmio_handler *vioapic_handler = &vioapic_mmio_handler;
iot=__gpfn_is_io(vcpu->domain, src_pa>>PAGE_SHIFT);
v_plat = vmx_vcpu_get_plat(vcpu);
case GPFN_GFW:
break;
case GPFN_IOSAPIC:
+ if (!dir)
+ vioapic_handler->write_handler(vcpu, src_pa, s, *dest);
+ else
+ *dest = vioapic_handler->read_handler(vcpu, src_pa, s);
+ break;
case GPFN_FRAME_BUFFER:
case GPFN_LOW_MMIO:
low_mmio_access(vcpu, src_pa, dest, s, dir);
#include <asm/hw_irq.h>
#include <asm/vmx_pal_vsa.h>
#include <asm/kregs.h>
+#include <asm/vmx_platform.h>
+#include <asm/vmx_vioapic.h>
-#define SHARED_VLAPIC_INF
-#ifdef V_IOSAPIC_READY
-static inline vl_apic_info* get_psapic(VCPU *vcpu)
-{
- shared_iopage_t *sp = get_sp(vcpu->domain);
- return &(sp->vcpu_iodata[vcpu->vcpu_id].apic_intr);
-}
-#endif
//u64 fire_itc;
//u64 fire_itc2;
//u64 fire_itm;
}
#ifdef V_IOSAPIC_READY
-void vlapic_update_shared_info(VCPU *vcpu)
-{
- //int i;
-
- vl_apic_info *ps;
-
- if (vcpu->domain == dom0)
- return;
-
- ps = get_psapic(vcpu);
- ps->vl_lapic_id = ((VCPU(vcpu, lid) >> 16) & 0xffff) << 16;
- printf("vl_lapic_id = %x\n", ps->vl_lapic_id);
- ps->vl_apr = 0;
- // skip ps->vl_logical_dest && ps->vl_dest_format
- // IPF support physical destination mode only
- ps->vl_arb_id = 0;
- /*
- for ( i=0; i<4; i++ ) {
- ps->tmr[i] = 0; // edge trigger
+/* Assist to check virtual interrupt lines */
+void vmx_virq_line_assist(struct vcpu *v)
+{
+ global_iodata_t *spg = &get_sp(v->domain)->sp_global;
+ uint16_t *virq_line, irqs;
+
+ virq_line = &spg->pic_irr;
+ if (*virq_line) {
+ do {
+ irqs = *(volatile uint16_t*)virq_line;
+ } while ((uint16_t)cmpxchg(virq_line, irqs, 0) != irqs);
+ vmx_vioapic_do_irqs(v->domain, irqs);
}
- */
+
+ virq_line = &spg->pic_clear_irr;
+ if (*virq_line) {
+ do {
+ irqs = *(volatile uint16_t*)virq_line;
+ } while ((uint16_t)cmpxchg(virq_line, irqs, 0) != irqs);
+ vmx_vioapic_do_irqs_clear(v->domain, irqs);
+ }
+}
+
+void vmx_virq_line_init(struct domain *d)
+{
+ global_iodata_t *spg = &get_sp(d)->sp_global;
+
+ spg->pic_elcr = 0xdef8; /* Level/Edge trigger mode */
+ spg->pic_irr = 0;
+ spg->pic_last_irr = 0;
+ spg->pic_clear_irr = 0;
}
-void vlapic_update_ext_irq(VCPU *vcpu)
+int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint16_t dest)
{
- int vec;
+ return (VLAPIC_ID(s->lapic_info[number]) == dest);
+}
+
+struct vlapic* apic_round_robin(struct domain *d,
+ uint8_t dest_mode,
+ uint8_t vector,
+ uint32_t bitmap)
+{
+ uint8_t bit;
+ vmx_vioapic_t *s;
- vl_apic_info *ps = get_psapic(vcpu);
- while ( (vec = highest_bits(ps->irr)) != NULL_VECTOR ) {
- clear_bit (vec, ps->irr);
- vmx_vcpu_pend_interrupt(vcpu, vec);
+ if (!bitmap) {
+ printk("<apic_round_robin> no bit on bitmap\n");
+ return NULL;
}
+
+ s = &d->arch.vmx_platform.vmx_vioapic;
+ for (bit = 0; bit < s->lapic_count; bit++) {
+ if (bitmap & (1 << bit))
+ return s->lapic_info[bit];
+ }
+
+ return NULL;
}
#endif
void vlsapic_reset(VCPU *vcpu)
{
int i;
-#ifdef V_IOSAPIC_READY
- vl_apic_info *psapic; // shared lapic inf.
-#endif
-
+
VCPU(vcpu, lid) = ia64_getreg(_IA64_REG_CR_LID);
VCPU(vcpu, ivr) = 0;
VCPU(vcpu,tpr) = 0x10000;
for ( i=0; i<4; i++) {
VLSAPIC_INSVC(vcpu,i) = 0;
}
+
#ifdef V_IOSAPIC_READY
- vlapic_update_shared_info(vcpu);
- //vlapic_update_shared_irr(vcpu);
+ vcpu->arch.arch_vmx.vlapic.vcpu = vcpu;
+ vmx_vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu);
#endif
DPRINTK("VLSAPIC inservice base=%lp\n", &VLSAPIC_INSVC(vcpu,0) );
}
#include <asm/vmx.h>
#include <xen/mm.h>
#include <public/arch-ia64.h>
+#include <asm/vmx_vioapic.h>
/* Global flag to identify whether Intel vmx feature is on */
u32 vmx_enabled = 0;
+unsigned int opt_vmx_debug_level = 0;
static u32 vm_order;
static u64 buffer_size;
static u64 vp_env_info;
* is registered here.
*/
void
-vmx_final_setup_domain(struct domain *d)
+vmx_final_setup_guest(struct vcpu *v)
{
- struct vcpu *v = d->vcpu[0];
vpd_t *vpd;
/* Allocate resources for vcpu 0 */
vpd = alloc_vpd();
ASSERT(vpd);
-// v->arch.arch_vmx.vpd = vpd;
- v->arch.privregs = vpd;
+ v->arch.privregs = vpd;
vpd->virt_env_vaddr = vm_buffer;
/* Per-domain vTLB and vhpt implementation. Now vmx domain will stick
vlsapic_reset(v);
vtm_init(v);
- /* Other vmx specific initialization work */
+ /* One more step to enable interrupt assist */
+ set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags);
}
typedef struct io_range {
return 0;
}
-void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c)
+void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c)
{
- struct domain *d = v->domain;
shared_iopage_t *sp;
ASSERT(d != dom0); /* only for non-privileged vti domain */
__va(__gpa_to_mpa(d, IO_PAGE_START));
sp = get_sp(d);
//memset((char *)sp,0,PAGE_SIZE);
- //sp->sp_global.eport = 2;
-#ifdef V_IOSAPIC_READY
- sp->vcpu_number = 1;
-#endif
/* TEMP */
d->arch.vmx_platform.pib_base = 0xfee00000UL;
- /* One more step to enable interrupt assist */
- set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags);
/* Only open one port for I/O and interrupt emulation */
- if (v == d->vcpu[0]) {
- memset(&d->shared_info->evtchn_mask[0], 0xff,
- sizeof(d->shared_info->evtchn_mask));
- clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]);
- }
-
- /* FIXME: only support PMT table continuously by far */
-// d->arch.pmt = __va(c->pt_base);
+ memset(&d->shared_info->evtchn_mask[0], 0xff,
+ sizeof(d->shared_info->evtchn_mask));
+ clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]);
+ /* Initialize the virtual interrupt lines */
+ vmx_virq_line_init(d);
- vmx_final_setup_domain(d);
+ /* Initialize iosapic model within hypervisor */
+ vmx_vioapic_init(d);
}
panic("Corruption: bad shared page: %lx\n", (unsigned long)vio);
#ifdef V_IOSAPIC_READY
- vlapic_update_ext_irq(v);
-#else
- //panic("IOSAPIC model is missed in qemu\n");
+ /* Confirm virtual interrupt line signals, and set pending bits in vpd */
+ vmx_virq_line_assist(v);
#endif
return;
}
return -EINVAL;
}
- vmx_setup_platform(v, c);
+ if (v == d->vcpu[0])
+ vmx_setup_platform(d, c);
+
+ vmx_final_setup_guest(v);
}
*regs = c->regs;
+ d->arch.sys_pgnr = c->sys_pgnr;
new_thread(v, regs->cr_iip, 0, 0);
v->vcpu_info->arch.evtchn_vector = c->vcpu.evtchn_vector;
}
v->arch.domain_itm_last = -1L;
- d->arch.sys_pgnr = c->sys_pgnr;
d->shared_info->arch = c->shared;
/* Don't redo final setup */
*/
printk("Dom0: 0x%lx, domain: 0x%lx\n", (u64)dom0, (u64)d);
if (vmx_dom0)
- vmx_final_setup_domain(dom0);
+ vmx_final_setup_guest(v);
set_bit(_VCPUF_initialised, &v->vcpu_flags);
switch (delivery_mode) {
case VLAPIC_DELIV_MODE_FIXED:
case VLAPIC_DELIV_MODE_LPRI:
- if (test_and_set_bit(vector, &target->irr[0]) && trig_mode == 1) {
+ if (test_and_set_bit(vector, &VLAPIC_IRR(target)) && trig_mode == 1) {
/* the level interrupt should not happen before it is cleard */
printk("<ioapic_inj_irq> level interrupt happen before cleard\n");
}
+#ifndef __ia64__
if (trig_mode)
test_and_set_bit(vector, &target->tmr[0]);
+#endif
result = 1;
break;
default:
if (dest_mode == 0) { /* Physical mode */
for (i = 0; i < s->lapic_count; i++) {
- if (s->lapic_info[i]->id == dest) {
+ if (VLAPIC_ID(s->lapic_info[i]) == dest) {
mask = 1 << i;
break;
}
#define RR7_SWITCH_SHIFT 12 /* 4k enough */
#include <public/io/ioreq.h>
-
extern void identify_vmx_feature(void);
extern unsigned int vmx_enabled;
extern void vmx_init_env(void);
-extern void vmx_final_setup_domain(struct domain *d);
+extern void vmx_final_setup_guest(struct vcpu *v);
extern void vmx_save_state(struct vcpu *v);
extern void vmx_load_state(struct vcpu *v);
-extern void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c);
+extern void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c);
#ifdef XEN_DBL_MAPPING
extern vmx_insert_double_mapping(u64,u64,u64,u64,u64);
extern void vmx_purge_double_mapping(u64, u64, u64);
{
return (shared_iopage_t *)d->arch.vmx_platform.shared_page_va;
}
+
+typedef unsigned long (*vmx_mmio_read_t)(struct vcpu *v,
+ unsigned long addr,
+ unsigned long length);
+
+typedef void (*vmx_mmio_write_t)(struct vcpu *v,
+ unsigned long addr,
+ unsigned long length,
+ unsigned long val);
+
+typedef int (*vmx_mmio_check_t)(struct vcpu *v, unsigned long addr);
+
+struct vmx_mmio_handler {
+ vmx_mmio_check_t check_handler;
+ vmx_mmio_read_t read_handler;
+ vmx_mmio_write_t write_handler;
+};
+
#endif /* _ASM_IA64_VT_H */
#define __ASM_IA64_VMX_PLATFORM_H__
#include <public/xen.h>
-
+#include <public/arch-ia64.h>
+#include <asm/vmx_vioapic.h>
struct mmio_list;
typedef struct virutal_platform_def {
- //unsigned long *real_mode_data; /* E820, etc. */
- unsigned long shared_page_va;
- //struct vmx_virpit_t vmx_pit;
- //struct vmx_handler_t vmx_handler;
- //struct mi_per_cpu_info mpci; /* MMIO */
+ unsigned long shared_page_va;
unsigned long pib_base;
unsigned char xtp;
struct mmio_list *mmio;
+ /* One IOSAPIC now... */
+ struct vmx_vioapic vmx_vioapic;
} vir_plat_t;
+static inline int __fls(uint32_t word)
+{
+ long double d = word;
+ long exp;
+
+ __asm__ __volatile__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d));
+ return word ? (exp - 0xffff) : -1;
+}
+
+/* This is a connect structure between vIOSAPIC model and vLSAPIC model.
+ * vlapic is required by vIOSAPIC model to manipulate pending bits, and
+ * we just map them into vpd here
+ */
+typedef struct vlapic {
+ struct vcpu *vcpu; /* Link to current vcpu */
+} vlapic_t;
+
+extern uint64_t dummy_tmr[];
+#define VCPU(_v,_x) _v->arch.privregs->_x
+#define VLAPIC_ID(l) (uint16_t)(VCPU((l)->vcpu, lid) >> 16)
+#define VLAPIC_IRR(l) VCPU((l)->vcpu, irr[0])
+
+/* As long as we register vlsapic to ioapic controller, it's said enabled */
+#define vlapic_enabled(l) 1
+#define vmx_apic_support(d) 1
+
+#define VLAPIC_DELIV_MODE_FIXED 0x0
+#define VLAPIC_DELIV_MODE_REDIR 0x1
+#define VLAPIC_DELIV_MODE_LPRI VLAPIC_DELIV_MODE_REDIR
+#define VLAPIC_DELIV_MODE_PMI 0x2
+#define VLAPIC_DELIV_MODE_SMI 0x2 /* For IA32 */
+#define VLAPIC_DELIV_MODE_RESERVED 0x3
+#define VLAPIC_DELIV_MODE_NMI 0x4
+#define VLAPIC_DELIV_MODE_INIT 0x5
+#define VLAPIC_DELIV_MODE_STARTUP 0x6 /* For IA32 */
+#define VLAPIC_DELIV_MODE_EXT 0x7
+
#endif
extern void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm);
extern void vtm_domain_out(VCPU *vcpu);
extern void vtm_domain_in(VCPU *vcpu);
-#ifdef V_IOSAPIC_READY
-extern void vlapic_update_ext_irq(VCPU *vcpu);
-extern void vlapic_update_shared_info(VCPU *vcpu);
-#endif
extern void vlsapic_reset(VCPU *vcpu);
extern int vmx_check_pending_irq(VCPU *vcpu);
extern void guest_write_eoi(VCPU *vcpu);
vmx_vcpu_set_lid(VCPU *vcpu, u64 val)
{
VCPU(vcpu,lid)=val;
-#ifdef V_IOSAPIC_READY
- vlapic_update_shared_info(vcpu);
-#endif
return IA64_NO_FAULT;
}
extern IA64FAULT vmx_vcpu_set_tpr(VCPU *vcpu, u64 val);
#ifndef __ASSEMBLY__
#include <asm/vtm.h>
+#include <asm/vmx_platform.h>
#include <public/arch-ia64.h>
#define VPD_SHIFT 17 /* 128K requirement */
struct arch_vmx_struct {
// struct virutal_platform_def vmx_platform;
// vpd_t *vpd;
- vtime_t vtm;
+ vtime_t vtm;
+ struct vlapic vlapic;
unsigned long vrr[8];
unsigned long vkr[8];
unsigned long cr_iipa; /* for emulation */
#define DBG_LEVEL_3 (1 << 3)
#define DBG_LEVEL_IO (1 << 4)
#define DBG_LEVEL_VMMU (1 << 5)
+#define DBG_LEVEL_IOAPIC (1 << 6)
extern unsigned int opt_vmx_debug_level;
#define VMX_DBG_LOG(level, _f, _a...) \
#define IOAPIC_REG_VERSION 0x1
-#ifdef __ia64__
-typedef union RedirStatus
-{
- uint64_t value;
- struct {
- uint16_t dest_id;
- uint8_t reserved[3];
- uint8_t reserve:7;
- uint8_t mask:1; /* interrupt mask*/
- uint8_t trigmod:1;
- uint8_t remoteirr:1;
- uint8_t polarity:1;
- uint8_t delivestatus:1;
- uint8_t destmode:1;
- uint8_t deliver_mode:3;
- uint8_t vector;
- } RedirForm;
-} RedirStatus;
-#else
typedef union RedirStatus
{
uint64_t value;
uint8_t trigmod:1;
uint8_t mask:1; /* interrupt mask*/
uint8_t reserve:7;
+#ifndef __ia64__
uint8_t reserved[4];
uint8_t dest_id;
+#else
+ uint8_t reserved[3];
+ uint16_t dest_id;
+#endif
} RedirForm;
} RedirStatus;
-#endif
#define IOAPIC_MEM_LENGTH 0x100
#define IOAPIC_ENABLE_MASK 0x0
#define vlapic_global_enabled(vlapic) \
!(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status))
+#define VLAPIC_IRR(t) ((t)->irr[0])
+#define VLAPIC_ID(t) ((t)->id)
+
typedef struct direct_intr_info {
int deliver_mode;
int source[6];